<?php
namespace lib\Data;

abstract class FileAccess implements DataAccess
{
	// 数据文件存放的storage子目录
	private $dir;
  
    public function __construct($directory)
    {
        $this->dir = STORAGE_DIR . DIRECTORY_SEPARATOR . $directory;
    }

    /**
     * 根据条件查找单个数据记录，以一个关联数组形式返回
     *
     * @param $condition array 等值判断条件组成的数组
     * @return array 返回包含数据记录的关联数组
     */
    public function find(Array $condition = [])
    {
        // 当前存放数据的目录若不存在,返回空数组
        if (!is_dir($this->dir) || !file_exists($this->dir)) {
            return [];
        }
        // 遍历当前数据目录下的所有文件
        $data = [];
        $directory = dir($this->dir);
        while ($file = $directory->read()) {
            $filePath = $this->dir . DIRECTORY_SEPARATOR . $file;
            //  遍历获取到的$file是文件，就读取并判断
            if (is_file($filePath)) {
                $content = file_get_contents($filePath);
                $array = $this->decode($content);

                $flag = true;
                foreach ($condition as $key => $value) {
                    if ($array[$key] != $value) {
                        $flag = false;
                        break;
                    }
                }
                if ($flag === true) {
                    $data = $array;
                    break;
                }
            }
        }
        return $data;
    }

    /**
     * 根据条件查找多个数据记录，以二维索引数组形式返回
     *
     * @param $condition array 等值判断条件组成的数组
     * @return array 返回包含多条数据记录的索引数组
     */
    public function get(Array $condition = [])
    {
        // 当前存放数据的目录若不存在,返回空数组
        if (!is_dir($this->dir) || !file_exists($this->dir)) {
            return [];
        }
        // 遍历当前数据目录下的所有文件
        $data = [];
        $directory = dir($this->dir);
        while ($file = $directory->read()) {
            $filePath = $this->dir . DIRECTORY_SEPARATOR . $file;
            if (is_file($filePath)) {
                $content = file_get_contents($filePath);
                $array = $this->decode($content);
                $flag = true;
                foreach ($condition as $key => $value) {
                    // $key = 'user.id'
                    if (strpos($key, '.')) {
                        $k1 = explode('.', $key)[0];
                        $k2 = explode('.', $key)[1];
                        if ($array[$k1][$k2] != $value) {
                            $flag = false;
                            break;
                        }
                    } else if ($array[$key] != $value) {
                        $flag = false;
                        break;
                    }
                }
                if ($flag === true) {
                    $data[] = $array;
                }
            }
        }
        return $data;
    }

    /**
     * 保存单个数据记录
     *
     * @param $data array 单个数据的关联数组
     */
    public function save(Array $data)
    {
        // 当前存放数据的目录若不存在，则创建
        if (!is_dir($this->dir) || !file_exists($this->dir)) {
            mkdir($this->dir);
        }
        // 把关联数组转换为json字符串
        $content = $this->encode($data);
        $fileName = $this->dir . DIRECTORY_SEPARATOR . $data['id'];
        $file = fopen($fileName, 'wb');
        fwrite($file, $content);
        fclose($file);
    }

    /**
     * 根据id删除指定的数据文件
     *
     * @param $id
     */
    public function delete($id)
    {
        //
    }

    /**
     * 将数组按照特定的方式编码成字符串
     *
     * @param array $array
     * @return string
     */
    protected abstract function encode(Array $array);

    /**
     * 将特定编码方式的字符串转换成数组
     *
     * @param string $str
     * @return array
     */
    protected abstract function decode($str);
}